using UnityEngine;
using UnityEngine.UIElements;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using UnityEditor;
using UnityEngine.Events;

public class SearchablePopup : VisualElement
{
    public string label
    {
        get => searchField.label;
        set => searchField.label = value;
    }

    public string value
    {
        get => searchField.value;
        set => searchField.value = value;
    }

    private TextField searchField;
    private ListView listView;
    private List<string> allOptions; // 所有原始选项
    private List<string> filteredOptions; // 过滤后的选项

    public new class UxmlFactory : UxmlFactory<SearchablePopup, UxmlTraits>
    {
    }

    public void RegisterValueChangedCallback(EventCallback<ChangeEvent<string>> callback)
    {
        searchField.RegisterValueChangedCallback(callback);
    }

    private string GetVisualTreeAssetPath()
    {
        // 1. 获取当前脚本的路径
        string[] guids = AssetDatabase.FindAssets($"t:Script {nameof(SearchablePopup)}");
        string scriptPath = AssetDatabase.GUIDToAssetPath(guids[0]); // 将GUID转换为资源路径[citation:3]
        string scriptDirectory = Path.GetDirectoryName(scriptPath);

        // 2. 假设UXML文件与脚本在同一目录下，名为 "MyUI.uxml"
        string uxmlRelativePath = $"{nameof(SearchablePopup)}.uxml";
        string fullUxmlPath = Path.Combine(scriptDirectory, uxmlRelativePath).Replace("\\", "/");

        return fullUxmlPath;
    }

    public SearchablePopup()
    {
        // 加载UXML模板并实例化
        var visualTree = AssetDatabase.LoadAssetAtPath<VisualTreeAsset>(GetVisualTreeAssetPath());
        visualTree.CloneTree(this);

        // 获取引用
        searchField = this.Q<TextField>("searchField");
        listView = this.Q<ListView>("optionsListView");

        // 初始化数据
        allOptions = new List<string>();
        filteredOptions = new List<string>();

        // 设置ListView
        SetupListView();

        // 注册搜索事件
        searchField.RegisterCallback<ChangeEvent<string>>(OnSearchValueChanged);
        searchField.RegisterCallback<FocusOutEvent>(evt =>
        {
            if (evt.target is VisualElement loseFoc && loseFoc == searchField)
            {
                HideDropdown();
            }
        });

        // 初始时隐藏列表，或者通过一个按钮来控制显示/隐藏
        listView.style.display = DisplayStyle.None;

        // 点击搜索框时显示列表，实际应用中你可能需要一个切换按钮
        searchField.RegisterCallback<ClickEvent>(ev => ShowDropdown());
    }

    private void SetupListView()
    {
        // 设置ListView的数据源和模板
        listView.makeItem = () => new Label(); // 创建每个列表项
        listView.bindItem = (item, index) => { (item as Label).text = filteredOptions[index]; };
        listView.itemsSource = filteredOptions;

        // 处理选择事件
        listView.onSelectionChange += OnItemSelected;

        // 设置列表样式，例如高度
        listView.style.height = 150;
    }

    private void OnSearchValueChanged(ChangeEvent<string> evt)
    {
        FilterOptions(evt.newValue);
    }

    private void FilterOptions(string searchText)
    {
        
        // 根据搜索文本过滤选项
        if (string.IsNullOrEmpty(searchText))
        {
            filteredOptions.Clear();
            filteredOptions.AddRange(allOptions);
        }
        else
        {
            filteredOptions = allOptions.Where(option =>
                option.ToLower().Contains(searchText.ToLower())).ToList();
        }

        listView.selectedIndex = -1;
        listView.itemsSource = filteredOptions;
        // 刷新ListView显示
        listView.Rebuild();

        // 显示下拉列表
        //ShowDropdown();
    }

    private void OnItemSelected(IEnumerable<object> selectedItems)
    {
        // 处理选项选择
        var selectedItem = selectedItems.FirstOrDefault() as string;
        if (selectedItem != null)
        {
            searchField.value = selectedItem;
            HideDropdown();
            // 在这里可以触发你自己的选择事件
        }
    }

    public void SetOptions(IEnumerable<string> options)
    {
        allOptions.Clear();
        allOptions.AddRange(options);
        filteredOptions.Clear();
        filteredOptions.AddRange(allOptions);
        listView.Rebuild();
    }

    private void ShowDropdown()
    {
        listView.style.display = DisplayStyle.Flex;
    }

    private void HideDropdown()
    {
        listView.style.display = DisplayStyle.None;
    }
}